﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
using System.Security.Claims;
using WebApi.Core.IRepository;

namespace WebApi.Core.Service.Middleware
{ 
    public class ConcurrentRefreshMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly IRefreshTokenRepository _refreshTokenRepository;
        private readonly ILogger<ConcurrentRefreshMiddleware> _logger;
        private readonly int _maxActiveTokens;

        public ConcurrentRefreshMiddleware(RequestDelegate next,IRefreshTokenRepository refreshTokenRepository,IConfiguration configuration,ILogger<ConcurrentRefreshMiddleware> logger)
        {
            _next = next;
            _refreshTokenRepository = refreshTokenRepository;
            _logger = logger;
            _maxActiveTokens = configuration.GetValue("RefreshTokenPolicy:MaxActiveTokens", 5);
        }

        public async Task InvokeAsync(HttpContext context)
        {
            // 仅拦截刷新令牌请求
            if (context.Request.Path.StartsWithSegments("/api/auth/refresh"))
            {
                var sw = Stopwatch.StartNew();

                try
                {
                    // 1. 获取用户身份
                    var userId = context.User.FindFirstValue(ClaimTypes.NameIdentifier);
                    if (string.IsNullOrEmpty(userId))
                    {
                        context.Response.StatusCode = 401;
                        await context.Response.WriteAsync("无效的用户凭证");
                        return;
                    }

                    // 2. 查询有效令牌数量
                    var activeCount = await _refreshTokenRepository.CountActiveTokensAsync(userId);

                    _logger.LogInformation($"用户 {userId} 当前有效刷新令牌数: {activeCount}");

                    // 3. 执行安全策略
                    if (activeCount >= _maxActiveTokens)
                    {
                        _logger.LogWarning($"检测到用户 {userId} 异常并发请求，已触发安全机制");

                        // 撤销所有令牌
                        await _refreshTokenRepository.RevokeAllTokensAsync(userId);

                        context.Response.StatusCode = 429; // Too Many Requests
                        await context.Response.WriteAsync("检测到异常活动，请重新登录");
                        return;
                    }
                }
                finally
                {
                    sw.Stop();
                    _logger.LogDebug($"并发检查耗时: {sw.ElapsedMilliseconds}ms");
                }
            }

            // 4. 继续处理请求
            await _next(context);
        }
    }
}
